package com.liuwei.spring.cloud.configuration;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.liuwei.spring.cloud.framework.constants.CaffeineCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * @author : CaffineConfiguration
 * @version V1.0
 * @date: 2024/5/13 5:23 PM
 * @Description: TODO
 */
@Slf4j
@Configuration
public class CaffeineConfiguration {

    @Bean(CaffeineCache.CACHE_MANAGER)
    public CacheManager caffeineCacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(buildCaffeine(Duration.ofSeconds(30)));

        // 自定义Cache
        if(ArrayUtils.isNotEmpty(CaffeineCache.CacheProperty.values())){
            for (CaffeineCache.CacheProperty config: CaffeineCache.CacheProperty.values()){
                Duration duration = null;
                // 如果过期时间小于 0; 则默认不过期
                if(config.getTtl()<0){
                    continue;
                }
                // 如果过期时间大于等于0; 设置对应的过期时间
                if(TimeUnit.NANOSECONDS.equals(config.getUnit())){
                    duration = Duration.ofNanos(config.getTtl());
                }
                if(TimeUnit.MICROSECONDS.equals(config.getUnit())){
                    duration = Duration.ofNanos(config.getTtl()*1000);
                }
                if(TimeUnit.MILLISECONDS.equals(config.getUnit())){
                    duration = Duration.ofMillis(config.getTtl());
                }
                if(TimeUnit.SECONDS.equals(config.getUnit())){
                    duration = Duration.ofSeconds(config.getTtl());
                }
                if(TimeUnit.MINUTES.equals(config.getUnit())){
                    duration = Duration.ofMinutes(config.getTtl());
                }
                if(TimeUnit.HOURS.equals(config.getUnit())){
                    duration = Duration.ofHours(config.getTtl());
                }
                if(TimeUnit.DAYS.equals(config.getUnit())){
                    duration = Duration.ofDays(config.getTtl());
                }
                log.info("cacheName:{}",config.name());
                cacheManager.registerCustomCache(config.name(),buildCaffeine(duration).build());
            }
        }
        return cacheManager;
    }

    private Caffeine<Object, Object> buildCaffeine(Duration duration){
        if(ObjectUtils.isNotNull(duration)){
            return Caffeine.newBuilder()
                    .expireAfterWrite(duration)
                    .initialCapacity(100)
                    .maximumSize(1000)
                    .recordStats();
        }else{
            return Caffeine.newBuilder()
                    .initialCapacity(100)
                    .maximumSize(1000)
                    .recordStats();
        }
    }
}
